﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace HistoryOrdersParser
{
    class Program
    {
        public const string period = "_20120101_20120618";

        static void Main(string[] args)
        {
            List<Order> closedOrders = new List<Order>();
            List<Order> openedOrders = new List<Order>();

            char[] delimiterChars = { ' ','\t' };
            string[] lines = System.IO.File.ReadAllLines(@"test" + period + ".txt");
            string[] objs=null;

            Order newOrder = null;
            Order existOrder = null;
            int orderNumber = 0;
            decimal orderResult = 0;

            foreach (string line in lines)
            {
                objs = line.Split(delimiterChars);

                if (objs[3] == OrderType.buy.ToString() || objs[3] == OrderType.sell.ToString())
                {
                    newOrder = new Order();
                    newOrder.OpenDate = DateTime.Parse(objs[1] + " " + objs[2]);
                    newOrder.OrderDirection = objs[3] == OrderType.buy.ToString() ? OrderType.buy : OrderType.sell;
                    newOrder.OrderNumber = Int32.Parse(objs[4]);
                    newOrder.OpenPrice = Decimal.Parse(objs[6]);

                    openedOrders.Add(newOrder);
                }

                if (objs[3] == "close" || objs[3] == "s/l" || objs[3] == "t/p")
                {
                    orderNumber = Int32.Parse(objs[4]);
                    existOrder = openedOrders.Where(x => x.OrderNumber == orderNumber).First();
                    existOrder.CloseDate = DateTime.Parse(objs[1] + " " + objs[2]);
                    existOrder.ClosePrice = Decimal.Parse(objs[6]);

                    orderResult=0;
                    if (existOrder.OrderDirection == OrderType.buy)
                        orderResult = (existOrder.ClosePrice - existOrder.OpenPrice) * 10000;
                    else
                        orderResult = (existOrder.OpenPrice - existOrder.ClosePrice) * 10000;

                    existOrder.Result = Math.Round(orderResult,1);
                    closedOrders.Add(existOrder);
                    openedOrders.Remove(existOrder);
                }

            }

            PrepareStats(closedOrders.OrderBy(x=>x.OpenDate).ToList<Order>());

            Console.ReadLine();
        }

        static void PrepareStats(List<Order> closedOrders)
        {
            StringBuilder sb = new StringBuilder();
            TimeSpan fridayHolidayHour=new TimeSpan(18,0,0);
            int allOrders = 0;
            int profitableOrders = 0;
            decimal profitability = 100;

            sb.AppendLine(PrepareDayliResults(DayOfWeek.Monday, closedOrders));
            sb.AppendLine(PrepareDayliResults(DayOfWeek.Tuesday, closedOrders));
            sb.AppendLine(PrepareDayliResults(DayOfWeek.Wednesday, closedOrders));
            sb.AppendLine(PrepareDayliResults(DayOfWeek.Thursday, closedOrders));
            sb.AppendLine(PrepareDayliResults(DayOfWeek.Friday, closedOrders));


            List<Order> fridayOrders = closedOrders.Where(x => x.OpenDate.DayOfWeek == DayOfWeek.Friday && x.OpenDate.TimeOfDay >= fridayHolidayHour).ToList<Order>();

            if (fridayOrders.Count > 0)
            {
                sb.AppendLine("Friday orders:");
                foreach (Order o in fridayOrders)
                    sb.AppendLine(o.ToString());

                allOrders = fridayOrders.Count;
                profitableOrders = fridayOrders.Where(x => x.Result > 0).Count();
                profitability = Math.Round((decimal)profitableOrders / allOrders, 1);
                sb.AppendLine(String.Format("{0}Friday orders result: {1} pp. {0}All orders: {2}\tProfitable orders: {3}\tProfitability: {4}\tMore than 100pp loss count:{5}{0}", Environment.NewLine, fridayOrders.Sum(x => x.Result),
                                            allOrders, profitableOrders, profitability, fridayOrders.Where(x=>x.Result<=-100).Count()));
            }

            TimeSpan mondayStartTime = new TimeSpan(18, 45, 0);
            List<Order> mondayOrders = closedOrders.Where(x => x.OpenDate.DayOfWeek == DayOfWeek.Monday && x.OpenDate.TimeOfDay <= mondayStartTime).ToList<Order>();

            if (mondayOrders.Count > 0)
            {
                sb.AppendLine("Monday affected by friday orders:");
                foreach (Order o in mondayOrders)
                    sb.AppendLine(o.ToString());

                allOrders = profitableOrders = 0;
                profitability = 100;
                allOrders = mondayOrders.Count;
                profitableOrders = mondayOrders.Where(x => x.Result > 0).Count();
                profitability = Math.Round((decimal)profitableOrders / allOrders, 1);
                sb.AppendLine(String.Format("{0}Monday affected by friday result: {1} pp. {0}All orders: {2}\tProfitable orders: {3}\tProfitability: {4}\tMore than 100pp loss count:{5}{0}", Environment.NewLine, mondayOrders.Sum(x => x.Result),
                                            allOrders, profitableOrders, profitability,mondayOrders.Where(x=>x.Result<=-100).Count()));

            }

            List<Order> bigLossOrders = closedOrders.Where(x => x.Result <= -100).ToList<Order>();
            sb.AppendLine("Big loss orders:"+Environment.NewLine);
            foreach (Order o in bigLossOrders)
                sb.AppendLine(o.ToString());

            System.IO.File.WriteAllText("result"+period+".txt", sb.ToString());

            Console.Write(sb.ToString());
        }

        static string PrepareDayliResults(DayOfWeek day, List<Order> closedOrders)
        {
            int allOrders = 0;
            int profitableOrders = 0;
            decimal profitability = 100;

            StringBuilder sb = new StringBuilder();

            List<Order> dayOrders = closedOrders.Where(x => x.OpenDate.DayOfWeek == day).ToList<Order>();
            if (dayOrders.Count > 0)
            {
                //sb.AppendLine("Friday orders:");
                //foreach (Order o in dayOrders)
                //    sb.AppendLine(o.ToString());

                allOrders = dayOrders.Count;
                profitableOrders = dayOrders.Where(x => x.Result > 0).Count();
                profitability = Math.Round((decimal)profitableOrders / allOrders, 1);
                sb.AppendLine(String.Format("{0}{5} orders result: {1} pp. {0}All orders: {2}\tProfitable orders: {3}\tProfitability: {4}\tMore than 100pp loss count:{6}{0}", Environment.NewLine, dayOrders.Sum(x => x.Result),
                                            allOrders, profitableOrders, profitability, day, dayOrders.Where(x=>x.Result<=-100).Count()));
            }

            return sb.ToString();
        }
    }
}
